package org.secur.eave

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.RemoteException
import android.util.Log
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.github.shadowsocks.Core
import com.github.shadowsocks.R
import org.secur.eave.util.BaseUtil.Companion.requestPermission
import com.github.shadowsocks.aidl.IShadowsocksService
import com.github.shadowsocks.aidl.ShadowsocksConnection
import com.github.shadowsocks.aidl.TrafficStats
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.database.ProfileManager
import com.github.shadowsocks.databinding.ActivityMainBinding
import com.github.shadowsocks.utils.StartService
import org.secur.eave.ui.ChoiceActivity
import org.secur.eave.ui.SettingActivity
import org.secur.eave.util.BaseUtil
import org.secur.eave.util.BaseUtil.Companion.checkVpnConnection
import org.secur.eave.util.BaseUtil.Companion.decodeStealthServer
import org.secur.eave.util.BaseUtil.Companion.formatDataRate
import org.secur.eave.util.BaseUtil.Companion.formatDataRateTotal
import org.secur.eave.util.BaseUtil.Companion.getIPAddress
import org.secur.eave.util.BaseUtil.Companion.stateListener
import org.secur.eave.util.MMKVUtil
import timber.log.Timber
class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback {
	
	private var state = BaseService.State.Idle
	private val connect = registerForActivityResult(StartService()) {}
	private val connection = ShadowsocksConnection(true)
	private lateinit var binding: ActivityMainBinding
	
	private var isShow = false
	
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		binding = ActivityMainBinding.inflate(layoutInflater)
		setContentView(binding.root)
		
		requestPermission(this)
		
		setupClickListeners()
		
		
		changeState(BaseService.State.Idle, animate = false)
		connection.connect(this, this)
		initClick()
		setSpeed()
	}
	
	private fun setSpeed() {
		binding.ip.text = getIPAddress()
		
		val stringValue = MMKVUtil.getStringValue()
		decodeStealthServer(stringValue.toString(), onSuccess = { ip ->
			binding.textView4.text = ip
		}, onFailure = { error ->
			Log.d("xianban", "$error")
		})
		
		binding.nodeLayout.setOnClickListener {
			Intent(
				this@MainActivity, ChoiceActivity::class.java
			).also {
				startActivity(it)
			}
		}
	}
	
	private fun initClick() {
		binding.setting.setOnClickListener {
			Intent(this, SettingActivity::class.java).also {
				startActivity(it)
			}
		}
	}
	
	private fun setupClickListeners() {
		binding.statusImg.setOnClickListener {
			val profiles = Profile.findAllUrls(
				data = MMKVUtil.getStringValue(), feature = null
			)
			profiles.firstOrNull()?.let { profile ->
				ProfileManager.createProfile(profile)
				Core.switchProfile(profile.id)
			}
			toggleConnection()
			isShow = true
			getStatus()
		}
		
		
		
	}
	
	private fun getStatus() {
		Handler(Looper.getMainLooper()).postDelayed({
			
			checkVpnConnection(this@MainActivity){
				
				if (it && isShow){
					Toast.makeText(this@MainActivity, "Connect", Toast.LENGTH_SHORT).show()
					isShow = false
				}
				if (!it && isShow){
					Toast.makeText(this@MainActivity, "Disconnect", Toast.LENGTH_SHORT).show()
					isShow = false
				}
			}
			
		},1500)
	}
	
	@SuppressLint("SetTextI18n")
	fun setImage(status: Boolean) {
		if (status) {
			binding.statusImg.setBackgroundResource(R.drawable.yes)
			binding.status.text = "Connect"
		} else {
			binding.statusImg.setBackgroundResource(R.drawable.no)
			binding.status.text = "Wait Connect"
		}
	}
	
	override fun stateChanged(state: BaseService.State, profileName: String?, msg: String?) {
		changeState(state, msg)
		if (state == BaseService.State.Connected) {
			setImage(true)
			
		} else {
			setImage(false)
			
		}
	}
	
	@SuppressLint("BinaryOperationInTimber")
	override fun trafficUpdated(profileId: Long, stats: TrafficStats) {
		if (profileId == 0L) {
			binding.upAll.text = formatDataRate(stats.txRate)
			binding.ups.text = formatDataRateTotal(stats.txTotal)
			
			binding.dos.text = formatDataRate(stats.rxRate)
			binding.doAll.text = formatDataRateTotal(stats.rxTotal)
		}
	}
	
	private fun changeState(state: BaseService.State, msg: String? = null, animate: Boolean = true) {
		this.state = state
		stateListener?.invoke(state)
	}
	
	private fun toggleConnection() {
		if (state.canStop) {
			Core.stopService()
		} else {
			connect.launch(null)
		}
	}
	
	override fun onServiceConnected(service: IShadowsocksService) {
		changeState(
			try {
				BaseService.State.values()[service.state]
			} catch (_: RemoteException) {
				BaseService.State.Idle
			}
		)
	}
	
	override fun onServiceDisconnected() {
		changeState(BaseService.State.Idle)
	}
	
	override fun onBinderDied() {
		connection.disconnect(this)
		connection.connect(this, this)
	}
	
	override fun onStart() {
		super.onStart()
		connection.bandwidthTimeout = 500
	}
	
	override fun onStop() {
		connection.bandwidthTimeout = 0
		super.onStop()
	}
	
	override fun onDestroy() {
		super.onDestroy()
		connection.disconnect(this)
	}
}

